var nhttp = require("@native.http");
var error = require("error.js");

var __FILE__ = "http.js";
var ERR = new error.ThrowError(__FILE__);

function format_headers(headers) {
        var headerStr = "";

        var keys = Object.keys(headers);
        var key = null,
            value = null;
        for (var i = 0; i < keys.length; i++) {
            key = keys[i];
            value = headers[key];
            headerStr += key + ":" + value + "\r\n";
        }
        headerStr += "\r\n";

        return headerStr;
}

function asset_options(options) {
    if (options.url == undefined || options.url == null || options.url == "" || typeof options.url != "string") return false;
    if(options.responseType == undefined){
        options.responseType = "text";
    }
    return true;
}

function Request(options) {
    this.__id__ = -1;
    this.options = options;

    this.init = function () {
        var res = asset_options(this.options)
        if (res == false) {
            ERR.trace("Request", 37, "HTTP_OPTION_ERROR", "parameters invaild");
        }

        this.__id__ = globalThis.eventbus.on(this, "recv", this.responseCallback);

        var url = this.options.url;
        var method = this.options.method;
        var timeout = this.options.timeout;
        var responseType = this.options.responseType;
        var data = JSON.stringify(this.options.data);
        var headerStr = format_headers(this.options.headers);

        nhttp.request(
            method,
            url,
            headerStr,
            data,
            responseType,
            timeout,
            this.__id__
        );
    }

    this.responseCallback = function(buffer, statusCode, headers) {
        var options = this.options;

        var failCallback = options.fail;
        var successCallback = options.success;
        var completeCallback = options.complete;
        var validateStatusCallback = options.validateStatus;
    
        // if (options.responseType == "json") {
        //     buffer = JSON.stringify(buffer.toString());
        // } else if (options.responseType == "blob") {
        //     // ��������
        // } else {
        //     console.log("//////////////////")
        //     buffer = buffer.toString();
        // }
    
        var result = {
            data: buffer,
            statusCode: statusCode,
            headers: headers,
            config: {
                url: options.url,
                data: options.data,
                method: options.method,
                headers: options.headers,
                timeout: options.timeout,
            },
        };
    
        var success = false;
        if (typeof validateStatusCallback == "function") {
            success = validateStatusCallback(statusCode);
            if (typeof success != "boolean") {
                throw new Error("validate status function must be return a boolean type");
            }
        } else if (statusCode >= 200 && statusCode < 300) {
            success = true;
        }
    
        if (success == true && typeof successCallback == "function") {
            successCallback(result);
        } else if (typeof failCallback == "function") {
            failCallback(result);
        }
        if (typeof completeCallback == "function") {
            completeCallback(result);
        }
    
        globalThis.eventbus.detach(this);
        // utils.logger.error(`remove event bus ${options.__module__} ${options.__id__}`);
    };
}

function request(options) {
    var req = new Request(options);
    req.init()
    return req;
}
